package au.edu.unsw.editingtool.db;

import java.sql.SQLException;
import java.util.Date;
import java.util.Enumeration;
import java.util.Hashtable;

import au.edu.unsw.editingtool.global.EditingToolException;

public class DBSession extends DBManager {
		
	private String SID;
	
	protected void setupDBMapping() {
		if (MappingTable.size() > 0)
			return;
		MappingTable.put("SID", "sid");		
		MappingTable.put("SessionID", "session_id");
		MappingTable.put("Username", "username");
		MappingTable.put("Date", "lastaccessdate");
		MappingTable.put("Timeout", "timeout");
		MappingTable.put("isLogin", "isLogin");
	}
	
	public DBSession() {
		this.table = "session";
		this.primaryKeys = new String[]{"SID"};
		this.setupDBMapping();
	}
	
	public String addSession(String sessionid, String username, String date, String timeout, String isLogin) throws EditingToolException, SQLException, ClassNotFoundException {
		this.setTable(this.table, "");
		Hashtable<String,String> sessionInfo = new Hashtable<String,String>();
		sessionInfo.put("SessionID",sessionid);
		sessionInfo.put("Username",username);
		sessionInfo.put("Date",date);
		sessionInfo.put("Timeout",timeout);
		sessionInfo.put("isLogin",isLogin);
		this.setColumnValues(sessionInfo);		
		this.initDB();		
		this.insert(true, false);
		this.SID = this.getGenerateKey();
		this.clean();		
		return this.SID;
	}
	
	// Get the generated key which is SID
	public String getReturnKey() {
		return this.SID;
	}
	
	public boolean isLoginValid(String sid, String sessionid, String username) throws EditingToolException, SQLException, ClassNotFoundException {
		boolean result = false;
		
		String fields[] = {"SID","isLogin"};		
		this.setTable(this.table, "");
		this.setFieldsCondition("SID", this.setEqual(sid));
		this.setFieldsCondition("SessionID", this.setEqual(sessionid));
		this.setFieldsCondition("Username", this.setEqual(username));								
		this.addField(fields);
		
		this.initDB();
		this.selectRecords();
		if (this.ResultSet == null) {
			System.out.println("[DBGROUP] isLoginValid Resultset = NULL");
			this.clean();
			return false;
		}
		int count =0;
		while(ResultSet.next())
		{
			count++;
			result = (Boolean) ResultSet.getObject(2);
		}
		if(count==1)
		{				
			System.out.println("[DBGROUP] isLoginValid Resultset = 1");
			this.clean();
			return result;			
		}
		else
		{
			this.clean();
			return false;
		}
	}
	public void updateLastAccessTime(String sid, String lastaccesstime)throws EditingToolException, SQLException, ClassNotFoundException 
	{
		this.setTable(this.table, "");
		Hashtable<String,String> sessionInfo = new Hashtable<String,String>();
		String fields[] = {"SID","Date","Timeout"};
		sessionInfo.put("SID",sid);		
		sessionInfo.put("Date",lastaccesstime);		
		this.setColumnValues(sessionInfo);	
		
		this.initDB();
		this.insert(false,true);	
		System.out.println("[DBGROUP] updateLastAccessTime : Update DbSession last access time on sid="+sid);
		this.clean();
	}
	
	// Clean old user session on the table
	public int cleanUserSession(String sid, String sessionid, String username) throws EditingToolException, SQLException, ClassNotFoundException 
	{
		int result = 0;
		String fields[] = {"SID","SessionID","Date","Timeout"};		
		this.setTable(this.table, "");		
		this.setFieldsCondition("Username", this.setEqual(username));								
		this.addField(fields);
		this.initDB();
		this.selectRecords();
		if (this.ResultSet == null) {
			this.clean();
			return result;
		}
		
		Hashtable<Long,String[]> dbusersessions = new Hashtable<Long,String[]> ();
		while(ResultSet.next())
		{			
			Long dbsid = (Long) ResultSet.getObject(1);
			String dbsessionid = (String) ResultSet.getObject(2).toString();
			String dbdate = ResultSet.getObject(3).toString();
			String timeout = ResultSet.getObject(4).toString();
			String[] sessiondata = {dbsessionid,dbdate,timeout};			
			dbusersessions.put(dbsid, sessiondata);
		}
		this.clean();
		Enumeration dbsidkeys = dbusersessions.keys();
				
		while(dbsidkeys.hasMoreElements())
		{
			Long dbsidkey = (Long) dbsidkeys.nextElement();					
			String [] sessiondata = (String[]) dbusersessions.get(dbsidkey);
			Long lastaccess = null;
			Integer timeout = null;
			String javasessionid = null;
			try
			{
				javasessionid = (String)sessiondata[0];
				if(Integer.parseInt(sid) == dbsidkey && sessionid.compareTo(javasessionid)==0)
					continue;
				lastaccess = Long.parseLong(sessiondata[1]);
				timeout= Integer.parseInt(sessiondata[2]);
			}
			catch(Exception ex)
			{
				ex.printStackTrace();
			}
			System.out.println ("[DBGROUP] cleanUserSession : Session info = "+dbsidkey+"|"+lastaccess+"|"+javasessionid+"|"+lastaccess+"|"+timeout);
			
			Long currenttime = (new Date()).getTime();
			Long lastaccestimeout = (lastaccess+(timeout*1000)); 
			
			if(currenttime > lastaccestimeout)
			{		
				System.out.println ("[DBGROUP] cleanUserSession : Session "+dbsidkey+" "+javasessionid+" is deleted : current time="+currenttime+",lastaccesstime with timeout="+lastaccestimeout);
				this.deleteSession(dbsidkey.toString(), javasessionid, username);
			}			
			result++;			
		}				
		return result;
	}
	
	public void deleteSession(String sid, String sessionid, String username)
	{
		boolean result = false;
		String fields[] = {"SID","isLogin"};		
		this.setTable(this.table, "");
		this.setFieldsCondition("Username", this.setEqual(username));
		this.setFieldsCondition("SessionID", this.setEqual(sessionid));
		this.setFieldsCondition("SID", this.setEqual(sid));						
		this.addField(fields);
		try
		{
			this.initDB();
			this.deleteRecord();
			this.clean();
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}
	
	public void deleteSession(String sessionid, String username)
	{
		boolean result = false;
		String fields[] = {"SID","isLogin"};		
		this.setTable(this.table, "");
		this.setFieldsCondition("Username", this.setEqual(username));
		this.setFieldsCondition("SessionID", this.setEqual(sessionid));					
		this.addField(fields);
		try
		{
			this.initDB();
			this.deleteRecord();
			this.clean();
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}
}
